const common = require('../libs/common');
const db = require('../libs/db');
const _ = require('underscore');
const moment = require('moment');
let now = new Date();
let daydate = '2019-09-01';//new Date(now.setDate(now.getDate() - 3)).toLocaleDateString();

module.exports = {
    async api_optimization(ctx, channel, query_set, product_ids) {
        query_set = query_set && query_set != '' ? query_set + ' and ' : '';
        let channel_conversion = 0;
        let cusr_conver = [];
        let cold_zone = [];
        let hot_zone = [];
        let channeldata = await this.getredis(ctx, channel);
        if (channeldata) {
            channel_conversion = channeldata;
        }else{
            // 计算三天内该渠道转化率
           
            let whereStr = query_set + ` channel='${channel}' and push_date> DATE('${daydate}') and pull_status=1 and error_msg IS NUll `;
            let order_count = await db.queryCount(ctx, 'loan_order', whereStr);
            let review_pass = await db.queryCount(ctx, 'loan_order', whereStr + ' and order_status IN (175, 180, 200)');
            if (order_count !== 0) {
                channel_conversion = parseInt(common.mul(common.div(review_pass, order_count), 100));
                await this.setredis(ctx,channel, channel_conversion, 1);
            }
        }

        let cusr_converdata = await this.getredis(ctx, "cusr_conver");
        if (cusr_converdata) {
            cusr_conver = cusr_converdata;
        } else {
            // 计算三天内该渠道转化率
            let whereStr = query_set + `push_date> DATE('${daydate}') and pull_status=1 and error_msg IS NUll`;
            let product_list = await db.querysql(ctx,`select distinct product_id from loan_order  where ${whereStr}`);
            let sqlStr = `SELECT a.id FROM products_product a INNER JOIN moduelconfig_product b ON a.id= b.product_id 
            WHERE a.api_type !=0 AND a.product_status=0 AND a.is_active=1 AND b.is_active=1 AND b.is_recommend=1`;
            let product_objs = await db.querysql(ctx, sqlStr);

            for (let index = 0; index < product_objs.length; index++) {
                const product = product_objs[index];
                if (product_list.findIndex((a) => {
                    return a.product_id === product.id;
                }) >= 0) {
                    conversion = await this.customer_conversion(ctx, whereStr, product.id);
                    cusr_conver.push([product.id, conversion]);
                } else {
                    cusr_conver.push([product.id, 0]);
                }
            }
            this.setredis(ctx,"cusr_conver", cusr_conver, 1);
        }

        let cold_zonedata = await this.getredis(ctx, "cold_zone");
        let hot_zonedata = await this.getredis(ctx,"hot_zone");
        if (cold_zonedata && hot_zonedata) {
            cold_zone = cold_zonedata;
            hot_zone = hot_zonedata;
        } else {
            cusr_conver.forEach((i) => {
                if (i[1] == 0) {
                    cold_zone.push(i);
                } else {
                    hot_zone.push(i);
                }
            })
            this.setredis(ctx, "cold_zone", cold_zone, 1);
            this.setredis(ctx,"hot_zone", hot_zone, 1);
        }

        let channel_for_custmerdata = await this.getredis(ctx,`${channel}_for_cust`);
        if (channel_for_custmerdata) {
            channel_for_custmer = channel_for_custmerdata;
        } else {
            channel_for_custmer =await this.channel_for_cust(ctx, channel, query_set);
            this.setredis(ctx, `${channel}_for_cust`, channel_for_custmer, 1);
        }

        let rate_li = this.conversion_rate_sort(channel_conversion, hot_zone, channel_for_custmer);
        rate_li = this.exclude_list(rate_li, product_ids);
        rate_li = this.sorted(rate_li, 1);
        let cold_li = [];
        if (channel == 0) {
            //三天内客户转化率前五
            cusr_conver = this.sorted(cusr_conver, 1);
            res_list = this.exclude_list(cusr_conver, product_ids);
            return res_list.slice(0, 4);
        } else if (channel > 0 && channel <= 4) {
            // 等级一
            cold_zone = this.exclude_list(cold_zone, product_ids);
            if (cold_zone.length >= 2) {
                cold_li = this.randomsample(cold_zone, 2);
            } else {
                cold_li = cold_zone;
            }
            rate_li = res_list.slice(0, 4 - cold_li.length);
        } else if (channel > 4 && channel <= 6) {
            // 等级二
            cold_zone = this.exclude_list(cold_zone, product_ids);
            if (cold_zone.length >= 2) {
                cold_li = this.randomsample(cold_zone, 2);
            } else {
                cold_li = cold_zone;
            }
            rate_li = res_list.slice(0, 4 - cold_li.length);
        } else if (channel > 4 && channel <= 6) {
            // 等级三
            cold_zone = this.exclude_list(cold_zone, product_ids);
            if (cold_zone.length >= 3) {
                cold_li = this.randomsample(cold_zone, 3);
            } else {
                cold_li = cold_zone;
            }
            rate_li = res_list.slice(0, 4 - cold_li.length);
        } else if (channel > 4 && channel <= 6) {
            // 等级四
            cold_zone = this.exclude_list(cold_zone, product_ids);
            if (cold_zone.length >= 3) {
                cold_li = this.randomsample(cold_zone, 3);
            } else {
                cold_li = cold_zone;
            }
            rate_li = res_list.slice(0, 4 - cold_li.length);
        } else if (channel > 4 && channel <= 6) {
            // 等级五
            cold_zone = this.exclude_list(cold_zone, product_ids);
            if (cold_zone.length >= 3) {
                cold_li = this.randomsample(cold_zone, 3);
            } else {
                cold_li = cold_zone;
            }
            rate_li = res_list.slice(0, 4 - cold_li.length);
        }
        rate_li = _.union(rate_li, cold_li);
        return rate_li;
    },
    async getredis(ctx, channel) {
        let data = await db.queryone(ctx, 'conversionrate_redis', '*', { name: channel, status: 1 });
        console.log(data);
        if (data) {
            return  eval("(" + data.value + ")");
        } else {
            return null;
        }
    },
    //客户转化率
    async  customer_conversion(ctx, whereStr_order, productid) {
        let order_count = await db.queryCount(ctx, 'loan_order', `${whereStr_order} and product_id=${productid}`);
        let review_pass = await db.queryCount(ctx, 'loan_order', `${whereStr_order} and product_id=${productid} and order_status IN (175, 180, 200)`);
        let conversion = 0;
        if (order_count != 0) {
            conversion = parseInt(common.mul(common.div(review_pass, order_count), 100));
        }
        return conversion;
    },
    // 渠道对应客户的转化率
    async  channel_for_cust(ctx,channel, query_set) {
        let whereStr_order = query_set + `channel='${channel}' and push_date> DATE(${daydate}) and pull_status=1 and error_msg is NULL`;
        let sqlStr = `SELECT a.id FROM products_product a INNER JOIN moduelconfig_product b ON a.id= b.product_id 
        WHERE a.api_type !=0 AND a.product_status=0 AND a.is_active=1 AND b.is_active=1 AND b.is_recommend=1`;
        let product_objs = await db.querysql(ctx, sqlStr);
        let product_list = await db.querylist(ctx, 'loan_order', ' distinct *');
        let channel_for_custmer = [];// 单渠道客户转化率
        for (let index = 0; index < product_objs.length; index++) {
            const product = product_objs[index];
            if (product_list.findIndex((a) => {
                return a.id === product.id;
            }) >= 0) {
                conversion = await this.customer_conversion(ctx, whereStr_order, product.id);
                channel_for_custmer.push([product.id, conversion]);
            } else {
                channel_for_custmer.push([product.id, 0]);
            }
        }
        return channel_for_custmer;
    },

    conversion_rate_sort(channel, conversion, channel_for_custmer) {
        var li = [];
        conversion.forEach((product) => {
            var id = product[0];
            product_rate = product[1];
            let channel_for_pro_rate = 0;
            channel_for_custmer.forEach((i) => {
                if (i[0] === id) {
                    channel_for_pro_rate = i[1];
                }
            })
            let rate = channel * 3 + product_rate * 2 + channel_for_pro_rate * 5;
            li.push([id, rate]);
        })
        return li;
    },
    async setredis(ctx, name, value, day) {
        let date = new Date();
        let obj = {
            name: name,
            value: value,
            created_time: moment(date).format('YYYY-MM-DD HH:mm:ss'),
            updated_time: moment(date).format('YYYY-MM-DD HH:mm:ss'),
            expred_time: new Date(date.setDate(date.getDate() + day)).toLocaleDateString(),
            day: day,
            status: 1
        };
        await ctx.db.query(`INSERT INTO conversionrate_redis 
        (name,value,created_time,updated_time,expred_time,day,status) VALUES(?,?,?,?,?,?,?)`
        , [name, JSON.stringify(value), obj.created_time, obj.updated_time, obj.expred_time, day, 1]);
    },
     exclude_list(rate_list, product_ids) {
        if (product_ids.length > 0) {
            let data = rate_list.filter((item) => {
                if (product_ids.findIndex((a) => {
                    return a == item[0];
                }) < 0) {
                    return true;
                }
            });
            return data;
        } else {
            return rate_list;
        }
    },
    sorted(items, index) {
        items =items.sort((a, b) => {
            return b[index] - a[index];
        });
        return items;
    },
    randomsample(items, num) {
        var return_array = [];
        var index_array = [];
        var i = 0;
        while (i < num) {
            var index = Math.floor(Math.random() * items.length);
            if (index_array.indexOf(index) < 0) {
                index_array.push(index);
                return_array.push(items[index]);
                i++;
            }
        }
        return return_array;
    },
}